

package streaming.control;

import java.awt.Color;
import java.io.IOException;

import javax.media.CannotRealizeException;
import javax.media.ControllerEvent;
import javax.media.ControllerListener;
import javax.media.GainControl;
import javax.media.Manager;
import javax.media.NoPlayerException;
import javax.media.Player;
import javax.media.PrefetchCompleteEvent;
import javax.media.RealizeCompleteEvent;
import javax.media.StartEvent;
import javax.media.StopEvent;
import javax.media.protocol.DataSource;
import javax.swing.JCheckBox;
import javax.swing.JComponent;
import javax.swing.JPanel;
import javax.swing.JSlider;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
/**
 * Klasa kontrolise zivotni ciklus <code>Player</code> objekta, koriscenog za reprodukciju audia. 
 * 
 * 
 * Implementira <code>ChangeListener</code>, i time pruza mogucnost da bilo se funkcionalnost volume
 * kontrole pridruzi bilo kojem JSlider objektu.
 * 
 * @author UrosKrkic & Radivoje Popovic
 *
 */

public class AudioControl implements Control, ControllerListener, ChangeListener{

	/**
	 * je objekat kojim upravlja <code>AudioControl</code>.
	 */
	private Player player;
	private JSlider slider;
	/**
	 * omogucava kontrolu nad jacinom zvuka
	 */
	private GainControl gain;
	
	/** 
	 * Kreira novi <code>AudioControl</code> objekat sa pridruzenim <code>Player</code> objektom.
	 * @param player  je <code>Player</code> objekat kojim upravlja <code>AudioControl</code>.
	 */
	public AudioControl(Player player) {
		this.player = player;
		this.player.addControllerListener(this);
		this.player.realize();

	}

	/**
	 * Kreira novi <code>AudioControl</code> objekat.
	 * <br>
	 * NOTE: <code>dataSource</code> mora biti aktivan prije upotrebe u konstruktoru.
	 * 
	 * @param dataSource se koristi za kreiranje novog <code>Player</code> objekta, cijim ce 
	 * zivotnim ciklusom upravljati <code>AudioControl</code>.
	 */
	public AudioControl(DataSource ds) throws IOException, NoPlayerException, CannotRealizeException{
		this(Manager.createPlayer(ds));
	}

	/**
	 * Kreira novi <code>AudioControl</code> objekat bez pridruzenog <code>Player</code> objekta.
	 */
	public AudioControl() {

	}


	/** 
	 * Upravljanje stanjima <code>Player</code> objekta
	 */
	@Override
	public void controllerUpdate(ControllerEvent e) {
		// TODO Auto-generated method stub
		System.out.println("audio: " + e);
		if(e instanceof RealizeCompleteEvent){
			if(e.getSource().equals(player)){
				player.prefetch();
				gain = player.getGainControl();
			}
		}
		else if(e instanceof PrefetchCompleteEvent){
			if(e.getSource().equals(player)){
				gain = player.getGainControl();
				player.start();
			}
		}
		else if(e instanceof StartEvent){
			if(e.getSource().equals(player)){
			}
		}
		else if(e instanceof StopEvent){
			if(e.getSource().equals(player)){
				player.close();
			}
		}
	}

	/**
	 * 
	 * @return aktuelni <code>Player</code> objekat
	 */
	public Player getPlayer() {
		return player;
	}

	
	/**
	 * Ukoliko je vec postojao pridruzeni <code>Player</code>,
	 * on ce biti zaustavljen i oslobodjen <code>ControllerListener</code>
	 * osluskivaca. Na njegovo mjesto se postavlja <code>player</code>
	 * @param player
	 */
	public void setPlayer(Player player) {
		if(this.player != null){
			this.player.stop();
			this.player.close();
			this.player.removeControllerListener(this);
		}

		this.player = player;
		this.player.addControllerListener(this);
		this.player.realize();

	}

	
	/**
	 * Radi isto sto i AudioControl#setPlayer(Player) samo sto se player
	 * kreira od proslijedjenog <code>ds</code>
	 * @param ds - novi DataSource objekat
	 * @throws NoPlayerException
	 * @throws IOException
	 * @see  AudioControl#setPlayer(Player)
	 */
	@Override
	public void setDataSource(DataSource ds) throws NoPlayerException, IOException {
		setPlayer(Manager.createPlayer(ds));
	}

	
	/**
	 * Kontrola slider-a i mute funkcionalnosti
	 */
	@Override
	public void stateChanged(ChangeEvent e) {
		if(e.getSource() instanceof JSlider){
			if(slider == null){
				slider = (JSlider)e.getSource();
			}

			if(gain != null){
				gain.setLevel(slider.getValue()/100.0f);
			}
		}
		else if(e.getSource() instanceof JCheckBox && gain != null){
			gain.setMute(((JCheckBox)e.getSource()).isSelected());
			if (!gain.getMute()) {
				if ( slider != null )
					gain.setLevel(slider.getValue()/100.0f);
				else {
					gain.setLevel(0.5f);
				}
			}
		}
	}

	public void stop() {
		if(player != null){
			player.stop();
		}
		
	}

	@Override
	public JComponent getVideoComponent() {
		// TODO Auto-generated method stub
		return null;
	}

	
}
